`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 	
// Engineer: Rohit Kulkarni, Vedang Vaidya
// 
// Create Date:    20:03:22 04/09/2014 
// Design Name: 
// Module Name:    nexys3fpga 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module Nexys3fpga (
	input 				clk100,          		// 100MHz clock from on-board oscillator
	input				btnl, btnr,					// pushbutton inputs - left and right
	input				btnu, btnd,					// pushbutton inputs - top and bottom
	input				btns,							// pushbutton inputs - center button
	input		[7:0]		sw,						// switch inputs
	
	output	[7:0]		led,  					// LED outputs	
	
	output 	[7:0]		seg,						// Seven segment display cathode pins
	output	[3:0]		an,						// Seven segment display anode pins	
	
	output	[3:0]		JA,						// JA Header
	output	[2:0]		vgaRed,
	output	[2:0]		vgaGreen,
	output	[2:1]		vgaBlue,
	output	Hsync,
	output	Vsync
); 

	// internal variables
	wire 	[7:0]		db_sw;					// debounced switches
	wire 	[4:0]		db_btns;					// debounced buttons
	
	wire				sysclk;					// 100MHz clock from on-board oscillator	
	wire				sysreset;				// system reset signal - asserted high to force reset
	
	wire 	[4:0]		dig3, dig2, 
						dig1, dig0;				// display digits
	wire 	[3:0]		decpts;					// decimal points
	wire  [11:0] 	address;
	wire 	[17:0] 	instruction;
	wire				clk;
	wire				bram_enable;
	wire	 [7:0]	in_port;
	wire 	 [7:0]	out_port;
	wire 	 [7:0]	port_id;
	wire				write_strobe;
	wire				k_write_strobe;
	wire				read_strobe;
	wire				interrupt;
	wire				interrupt_ack;
	wire				sleep;
	wire				reset;
	wire 	 [7:0]	MotCtl_in;		// Motor control input	
	wire	 [7:0] 	LocX_reg;		// X-coordinate of rojobot's location		
	wire	 [7:0]	LocY_reg;		// Y-coordinate of rojobot's location
	wire	 [7:0]	Sensors_reg;	// Sensor readings
	wire	 [7:0]	BotInfo_reg;	// Information about rojobot's activity
	wire	 [7:0]	LMDist_reg;		// left motor distance register
	wire	 [7:0]	RMDist_reg;		// right motor distance register
	
	wire 	 [10:0]	vid_row;			// video logic row address
	wire 	 [10:0]	vid_col;			// video logic column address
	wire 	 [1:0]	world_pixel;	// pixel (location) value
	wire				upd_sysregs;	// flag from PicoBlaze to indicate that the system registers 
	
	wire  clkfb_in, clk0_buf;
	wire	clk25;
	wire [1:0] 		icon_out;
	wire [10:0]	ICON_ROM_ADDR;
	wire [1:0]	ICON_ROM_DATA;
	
/******************************************************************/
/* CHANGE THIS SECTION FOR YOUR LAB 1                             */
/******************************************************************/		
	wire	[7:0]		left_pos, right_pos;
	wire 	[31:0]		digits_out;				// ASCII digits (Only for Simulation)

	// set up the display and LEDs
/*
	assign	dig3 = dig3;
	assign	dig2 = dig2;
	assign 	dig1 = dig1;
	assign	dig0 = dig0;
*/

//	assign	decpts = 4'b0000;					// d2 is on

//	assign	led = db_sw;					// leds show the debounced switches
	
/******************************************************************/
/* THIS SECTION SHOULDN'T HAVE TO CHANGE FOR LAB 1                */
/******************************************************************/			
	// global assigns
	assign	sysclk = clk100;
	assign 	sysreset = db_btns[0];
	assign	JA = {sysclk, sysreset, 2'b0};

	//instantiate the debounce module
	debounce 	DB (
		.clk(sysclk),	
		.pbtn_in({btnl,btnu,btnr,btnd,btns}),
		.switch_in(sw),
		.pbtn_db(db_btns),
		.swtch_db(db_sw)
	);	
		
	// instantiate the 7-segment, 4-digit display
	sevensegment SSB (
		// inputs for control signals
		.d0(dig0),
		.d1(dig1),
 		.d2(dig2),
		.d3(dig3),
		.dp(decpts),
		// outputs to seven segment display
		.seg(seg),			
		.an(an),				
		// clock and reset signals (100 MHz clock, active high reset)
		.clk(sysclk),
		.reset(sysreset),
		// ouput for simulation only
		.digits_out(digits_out)
	);

/******************************************************************/
/* CHANGE THIS DEFINITION FOR YOUR LAB 1                          */
/******************************************************************/							

	//Instantiate the program_rom
//	 proj1demo #(
//	.C_FAMILY		   ("S6"),   		//Family 'S6' or 'V6'
//	.C_RAM_SIZE_KWORDS	(1),  		//Program size '1', '2' or '4'
//	.C_JTAG_LOADER_ENABLE	(1))  	//Include JTAG Loader when set to '1' 
	 proj1demo program_rom (    						//Name to match your PSM file
// .rdl 			(kcpsm6_reset),
	.enable 		(bram_enable),
	.address 		(address),
	.instruction 	(instruction),
	.clk 			(sysclk)
	);

	//Instantiate kcpsm6
	kcpsm6 #(
	.interrupt_vector	(12'h3FF),
	.scratch_pad_memory_size(64),
	.hwbuild		(8'h00))
	BOT_CONTROL_CPU (
	.address 		(address),
	.instruction 	(instruction),
	.bram_enable 	(bram_enable),
	.port_id 		(port_id),
	.write_strobe 	(write_strobe),
	.k_write_strobe 	(k_write_strobe),
	.out_port 		(out_port),
	.read_strobe 	(read_strobe),
	.in_port 		(in_port),
	.interrupt 		(interrupt),
	.interrupt_ack 	(interrupt_ack),
	.reset 		(kcpsm6_reset),
	.sleep		(kcpsm6_sleep),
	.clk 			(sysclk)); 

	//Instantiate bot
	bot ROJOBOT(
		.MotCtl_in(MotCtl_in),		
		.LocX_reg(LocX_reg),			
		.LocY_reg(LocY_reg),	
		.Sensors_reg(Sensors_reg),	
		.BotInfo_reg(BotInfo_reg),	
		.LMDist_reg(LMDist_reg),		
		.RMDist_reg(RMDist_reg),		
		.vid_row({1'b0, 1'b0, vid_row[10:2]}),		
		.vid_col({1'b0, 1'b0, vid_col[10:2]}),		
		.vid_pixel_out(world_pixel),
		.clk(sysclk),
		.reset(sysreset),
		.upd_sysregs(upd_sysregs)
	);
	
	//Instantiate nexys_bot_if
	nexys_bot_if BOT_INTERFACE(
		.port_id(port_id),
		.out_port(out_port),
		.in_port(in_port),
		.write_strobe(write_strobe),
		.k_write_strobe(k_write_strobe),
		.read_strobe(read_strobe),
		.interrupt(interrupt),	          
		.interrupt_ack(interrupt_ack),
		
		.motctl(MotCtl_in),
		.locX(LocX_reg),
		.locY(LocY_reg),
		.botinfo(BotInfo_reg),
		.sensors(Sensors_reg),
		.lmdist(LMDist_reg),
		.rmdist(RMDist_reg),
		.upd_sysregs(upd_sysregs),
		
		.dig3(dig3),
		.dig2(dig2),
		.dig1(dig1),
		.dig0(dig0),
		.dp(decpts),

		.db_btns(db_btns),	
		.db_sw(db_sw),
		.led(led),
		.clk(sysclk)
	);

/*
	video_logic VIDEO_LOGIC(
	.LocX_reg(LocX_reg),			// X-coordinate of rojobot's location		
	.LocY_reg(LocY_reg),			// Y-coordinate of rojobot's location
	.Sensors_reg(Sensors_reg),	// Sensor readings
	.BotInfo_reg(BotInfo_reg),
	.clk_25MHZ(clk25),
	.reset(1'b0),
	.vid_pixel_out(world_pixel),
	
	.horiz_sync(Hsync),
	.vert_sync(Vsync),
	.red(vgaRed),
	.green(vgaGreen),
	.blue(vgaBlue)
	);
*/	  

	  
	BUFG CLK0_BUFG_INST(.I(clk0_buf), .O(clkfb_in));
	
	//Instantiate DCM
	DCM_SP #(
		.CLKDV_DIVIDE(1.5), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
		// 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
		.CLKFX_DIVIDE(1), // Can be any integer from 1 to 32
		.CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32
		.CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
		.CLKIN_PERIOD(10.0), // Specify period of input clock
		.CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE
		.CLK_FEEDBACK("1X"), // Specify clock feedback of NONE, 1X or 2X
		.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
		// an integer from 0 to 15
		.DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL
		.DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE
		.PHASE_SHIFT(0), // Amount of fixed phase shift from -255 to 255
		.STARTUP_WAIT("FALSE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE
		) DCM_SP_inst (
		.CLK0(clk0_buf), // 0 degree DCM CLK output
		.CLK180(), // 180 degree DCM CLK output
		.CLK270(), // 270 degree DCM CLK output
		.CLK2X(), // 2X DCM CLK output
		.CLK2X180(), // 2X, 180 degree DCM CLK out
		.CLK90(), // 90 degree DCM CLK output
		.CLKDV(clk25), // Divided DCM CLK out (CLKDV_DIVIDE)
		.CLKFX(), // DCM CLK synthesis out (M/D)
		.CLKFX180(), // 180 degree CLK synthesis out
		.LOCKED(), // DCM LOCK status output
		.PSDONE(), // Dynamic phase adjust done output
		.STATUS(), // 8-bit DCM status bits output
		.CLKFB(clkfb_in), // DCM clock feedback
		.CLKIN(clk100), // Clock input (from IBUFG, BUFG or DCM)
		.PSCLK(1'b0), // Dynamic phase adjust clock input
		.PSEN(1'b0), // Dynamic phase adjust enable input
		.PSINCDEC(1'b0), // Dynamic phase adjust increment/decrement
		.RST(1'b0) // DCM asynchronous reset input
	);
	// End of DCM_SP_inst instantiation		

	dtg DTG(
	.clock(clk25), 
	.rst(1'b0),
	.horiz_sync(Hsync),
	.vert_sync(Vsync),
	.video_on(video_on),		
	.pixel_row(vid_row), 
	.pixel_column(vid_col)
);

	coloriser COLORISER(
	.vid_pixel_out(world_pixel),
	.icon(icon_out),
	.video_on(video_on),
	.red(vgaRed),	
	.green(vgaGreen),
	.blue(vgaBlue)
 );
 
	icon	ICON(
	.pixel_row(vid_row),
	.pixel_column(vid_col),
	.LocX_reg(LocX_reg),			// X-coordinate of rojobot's location		
	.LocY_reg(LocY_reg),			// Y-coordinate of rojobot's location
	.BotInfo_reg(BotInfo_reg),	
	.icon(icon_out),
	.ROM_data(ICON_ROM_DATA),
	.ROM_addr(ICON_ROM_ADDR)
    );
 
	icon_rom ICON_ROM(
  .clka(clk25),
  .addra(ICON_ROM_ADDR),
  .douta(ICON_ROM_DATA)
);
	
	
endmodule
